﻿using System;
using System.IO;
using System.Reflection;

namespace Studio.Configuration
{

    /// <summary>
    /// Base Settings Class
    /// Take use of 
    /// </summary>
    public class ReflectionSettings
    {

        /// <summary>
        /// Empty Constructor
        /// </summary>
        public ReflectionSettings()
        { 
            
        }

        public ReflectionSettings(Stream stream)
        {
            string section = null;

            StreamReader reader = new StreamReader(stream);

            while (false == reader.EndOfStream)
            {
                string line = reader.ReadLine();

                if (line.StartsWith("#"))
                {
                    // skip comments
                    continue;
                }
                else if (line.EndsWith("]") && line.StartsWith("["))
                {
                    section = line.Substring(1, line.Length - 2);
                }
                else
                {
                    string[] data;
                    if (SettingSection == section)
                    {
                        data = line.Split(new char[] { '=' });
                        if (2 <= data.Length)
                        {
                            string propertyName = data[0].ToUpper().Trim();
                            string propertyValue = data[1];
                            try
                            {
                                Type type = this.GetType();
                                type.InvokeMember(propertyName,
                                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetField,
                                    new ConfigurationBinder(), this, new object[] { propertyValue });
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine(ex.StackTrace);
                                Console.WriteLine("[Load Configuration]{0} mapping Failed.", propertyName);
                            }
                        }
                    }
                    else
                    {
                        LoadSettings(section, line);
                    }
                }
            }
            Console.WriteLine("Load Config Loaded Successfully.");
        }

        public virtual void LoadSettings(string section, string data) {}


        public virtual string SettingSection
        {
            get
            {
                return "SETTINGS";
            }
        }

        public static ReflectionSettings Load(string file)
        {
            FileStream stream = null;
            StreamReader reader = null;
            try
            {
                stream = File.Open(file, FileMode.Open);
                return new ReflectionSettings(stream);
            }
            catch (Exception e)
            {
                Console.WriteLine("Load Config Failed.Exception:{0}.", e.Message);
                return null;
            }
            finally
            {
                if (null != reader) reader.Close();
                if (null != stream) stream.Close();
            }
        }

        public override string ToString()
        {
            string result = string.Empty;
            Type type = this.GetType();
            foreach (FieldInfo field in type.GetFields())
            {
                result += string.Format("{0}={1}\r\n", field.Name, field.GetValue(this));
            }
            return result;
        }
    }
}
